﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Shape.Mvp.Persistence.Conversations
{
	public interface IConversation : IDisposable, IEqualityComparer<IConversation>
	{
		// From uNhAddIns
		// http://fabiomaulo.blogspot.co.uk/2008/12/conversation-per-business-transaction.html

		string Id { get; }
		IDictionary<string, object> Context { get; }

		void Start();
		void Pause();
		void FlushAndPause();
		void Resume();
		void End();
		void Abort();

		event EventHandler<EventArgs> Starting;
		event EventHandler<EventArgs> Started;
		event EventHandler<EventArgs> Pausing;
		event EventHandler<EventArgs> Paused;
		event EventHandler<EventArgs> Resuming;
		event EventHandler<EventArgs> Resumed;
		event EventHandler<EventArgs> Ending;
		event EventHandler<EventArgs> Aborting;
		event EventHandler<EndedEventArgs> Ended;
		event EventHandler<OnExceptionEventArgs> OnException;
	}

	public enum ConversationAction
	{
		Start,
		Pause,
		FlushAndPause,
		Resume,
		End,
		Abort
	}

	public class EndedEventArgs : EventArgs
	{
		/// <summary>
		/// true if the event happen during disposing; false when the <see cref="IConversation.End"/>
		/// is explicit called. 
		/// </summary>
		public bool Disposing { get; set; }

		/// <summary>
		/// Initializes a new instance of the <see cref="EndedEventArgs"/> class
		/// </summary>
		/// <param name="disposing">true if the event happen during disposing</param>
		public EndedEventArgs(bool disposing)
		{
			Disposing = disposing;
		}
	}

	public class OnExceptionEventArgs : EventArgs
	{
		public OnExceptionEventArgs(ConversationAction action, Exception exception)
		{
			Action = action;
			Exception = exception;
			ReThrow = true;
		}

		public ConversationAction Action { get; set; }
		public Exception Exception { get; private set; }
		public bool ReThrow { get; set; }
	}
}
